package com.quyunshuo.module.home.activity.details

import android.Manifest
import android.animation.ValueAnimator
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Color
import android.os.Build.VERSION_CODES.M
import android.util.Log
import android.util.Size
import android.view.View
import android.widget.Toast
import androidx.activity.viewModels
import androidx.camera.core.CameraProvider
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageProxy
import androidx.camera.core.Preview
import androidx.camera.core.SurfaceRequest
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import com.blankj.utilcode.util.PermissionUtils
import com.quyunshuo.androidbaseframemvvm.base.ktx.gone
import com.quyunshuo.androidbaseframemvvm.base.ktx.visible
import com.quyunshuo.androidbaseframemvvm.common.constant.KEY_URL
import com.quyunshuo.androidbaseframemvvm.common.ext.click
import com.quyunshuo.androidbaseframemvvm.common.ui.BaseActivity
import com.quyunshuo.module.home.R
import com.quyunshuo.module.home.databinding.HomeActivityDetailsBinding
import com.quyunshuo.module.home.dialog.MessageDialog
import com.tencent.smtt.export.external.interfaces.SslError
import com.tencent.smtt.export.external.interfaces.SslErrorHandler
import com.tencent.smtt.export.external.interfaces.WebResourceRequest
import com.tencent.smtt.sdk.WebView
import com.tencent.smtt.sdk.WebViewClient
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.components.ActivityComponent
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.apache.commons.math3.complex.Complex
import org.apache.commons.math3.transform.DftNormalization
import org.apache.commons.math3.transform.FastFourierTransformer
import org.apache.commons.math3.transform.TransformType
import java.util.LinkedList
import java.util.concurrent.ExecutionException
import java.util.concurrent.Executors
import kotlin.math.roundToInt

/**
 * 首页
 *
 * @author Qu Yunshuo
 * @since 5/22/21 2:26 PM
 */
@AndroidEntryPoint
class DetailsActivity : BaseActivity<HomeActivityDetailsBinding, DetailsViewModel>() {

    companion object {
        private const val REQUEST_CAMERA_PERMISSION = 101
        private const val REQUEST_CODE_PERMISSIONS = 10
    }

    private val TAG = "DetailsActivity"
    var animator: ValueAnimator? = null;
    var setonConfirmListener: MessageDialog.Builder? = null

    /**
     * 通过 viewModels() + Hilt 获取 ViewModel 实例
     */
    override val mViewModel by viewModels<DetailsViewModel>()

    override fun createVB() = HomeActivityDetailsBinding.inflate(layoutInflater)

    override fun HomeActivityDetailsBinding.initView() {
        checkCameraPermission()

        //如果其他啥都没有做，那么在webview里面点击下一篇文章，也就是其他链接的时候，就会打开系统浏览器。如何解决这个问题呢？
        webView.webViewClient = mWebViewClient //如果不设置则跳系统浏览器，就实现一下就可以了。

        val url = intent?.getStringExtra(KEY_URL)
        webView.loadUrl(url)
        ivBack.click {
            finish()
        }


        /*
        最后一个参数 "上海市"​​：代表动画的 ​​结束值​​。
        ​​起始值​​：未显式指定，系统会通过反射调用 progress.getProvince() 获取当前属性值作为起始值。
         */
//        ObjectAnimator.ofObject(progress,"province",ProvinceEvaluatort(),"上海市").apply {
//            startDelay = 1000
//            duration =5000
//            start()
//        }

        //动画效果。注意，需要重绘。
//        val animate = ObjectAnimator.ofFloat(ivTest, "radius", 150f.px)
//        animate.startDelay = 1000
//        animate.start()

//        ivTest.animate()
//            .translationX(200f.px)
//            .setStartDelay(1000)

        btnOpenSett.click {
            //引导至设置页
            PermissionUtils.launchAppDetailsSettings()
        }
    }

//    override fun onResume() {
//        super.onResume()
//
//    }

    private fun checkCameraPermission() {

        when {
            PermissionUtils.isGranted(Manifest.permission.CAMERA) -> {
                // 已经有权限，执行相机操作
                openCamera()
                Log.d(TAG, "checkCameraPermission1: ")
            }
            //被用户拒绝过。
            ActivityCompat.shouldShowRequestPermissionRationale(
                this,
                Manifest.permission.CAMERA
            ) -> {
                // 解释为什么需要权限（用户之前拒绝过）在此进入界面的时候，我们需要显示按钮提示用户，或者客户取消后，
                // 结果我们知道了，我们也要通知客户。
                showPermissionExplanationDialog()

                Log.d(TAG, "checkCameraPermission2: ")
            }

            else -> {
                requestCameraPermission()
                Log.d(TAG, "checkCameraPermission3: ")
            }
        }

    }

    private fun showPermissionExplanationDialog() {
        setonConfirmListener = MessageDialog.Builder(this)
            .setMessage("需要获取相机权限")
            .setCancel("取消")
            .setConfirm("获取")
            .setonCancelListener {
                it?.dismiss()
            }
            .setonConfirmListener {
                it?.dismiss()
                requestCameraPermission()
            }

        setonConfirmListener?.show()

    }

    private lateinit var cameraProvider: ProcessCameraProvider
    private fun openCamera() {
        Log.d(TAG, "openCamera: ")
        mBinding.btnOpenSett.visibility = View.GONE

        // 步骤1：获取 CameraProvider 的 Future 对象（异步操作）
        // ProcessCameraProvider 是 CameraX 的核心管理类，负责摄像头生命周期和用例绑定
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        // 步骤2：添加监听器，在 Future 完成时执行回调
        cameraProviderFuture.addListener({
            try {
                // 步骤2.1：获取已完成的 CameraProvider 实例
                cameraProvider = cameraProviderFuture.get()
                // 步骤2.2：执行预览绑定逻辑
                bindPreview()
            } catch (e: ExecutionException) {
                Log.e("CameraX", "初始化失败: ${e.cause?.message}")
                Toast.makeText(this, "摄像头初始化失败", Toast.LENGTH_SHORT).show()
            } catch (e: InterruptedException) {
                Log.e("CameraX", "初始化被中断")
            }
            //步骤3：指定监听器的执行线程（主线程）
        }, ContextCompat.getMainExecutor(this))
    }

    private fun bindPreview() {
        // 步骤1：创建摄像头选择器，指定使用后置摄像头
        val cameraSelector = CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK) // 强制要求后置摄像头
            .build()

        // 步骤2：构建预览用例（Preview UseCase）
        val preview = Preview.Builder()
            .build()
        // 将预览视图的SurfaceProvider绑定到预览用例
        preview.setSurfaceProvider(mBinding.previewView.surfaceProvider)


        isMeasuring = true
        redValues.clear()
        // 配置图像分析
        val imageAnalysis = ImageAnalysis.Builder()
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .build()
        imageAnalysis.setAnalyzer(Executors.newSingleThreadExecutor()) { imageProxy ->
            if (isMeasuring) {
                // 获取图像亮度
                val buffer = imageProxy.planes[0].buffer
                val pixelData = buffer.asIntBuffer()
                var sumRed = 0L
                for (i in 0 until pixelData.capacity()) {
                    val pixel = pixelData.get(i)
                    sumRed += (pixel shr 16) and 0xFF // 提取红色通道
                }
                val avgRed = sumRed.toDouble() / pixelData.capacity()

                synchronized(redValues) {
                    redValues.add(avgRed)
                    if (redValues.size > bufferSize) {
                        redValues.removeFirst()
                    }
                }
            }
            imageProxy.close()
        }


        try {
            // 步骤3：将摄像头生命周期绑定到当前Activity
            cameraProvider.bindToLifecycle(
                this, // LifecycleOwner，通常为Activity或Fragment
                cameraSelector, // 摄像头选择器
                preview, // 预览用例
                imageAnalysis // 创建拍照用例（可选，按需添加）
            )
            // 启动心率计算
            startHeartRateCalculation()
        } catch (e: Exception) {
            // 🔽 优化点1：添加异常捕获，处理绑定失败（如摄像头被占用）
            // No supported surface combination is found for camera device - Id 打开了两次摄像头，导致问题的出现。
            Log.e("CameraX", "绑定摄像头失败: ${e.message}")
            Toast.makeText(this, "无法启动摄像头", Toast.LENGTH_SHORT).show()
            return
        }


    }

    private fun requestCameraPermission() {
        PermissionUtils.permission(Manifest.permission.CAMERA)
            .callback(object : PermissionUtils.FullCallback {
                override fun onGranted(granted: MutableList<String>) {
                    // 权限已授予
                    openCamera()
                }

                override fun onDenied(
                    deniedForever: MutableList<String>,
                    denied: MutableList<String>
                ) {
                    mBinding.btnOpenSett.visible()

//                    if (deniedForever.contains(Manifest.permission.CAMERA)) {
//                        // 用户永久拒绝（勾选“不再询问”）
//                    } else {
//                        // 用户拒绝但未勾选“不再询问”
//
//                    }
                }

            }).request()
    }

    /**
     * 处理各种通知 & 请求事件
     */
    private val mWebViewClient = object : WebViewClient() {
        /**
         * 网页加载完毕
         */
        override fun onPageFinished(webView: WebView?, url: String?) {
            super.onPageFinished(webView, url)
        }


        /**
         * 在 Android 7.0+ 设备上​​：
         *
         *         只会触发新方法​​（带 WebResourceRequest 参数）
         *         旧方法不会被调用
         *         所有链接跳转通过 view?.loadUrl(url) 加载
         */
        // 统一处理所有链接跳转
        override fun shouldOverrideUrlLoading(
            view: WebView?,
            request: WebResourceRequest?
        ): Boolean {
            val url = request?.url?.toString() ?: ""
            view?.loadUrl(url)
            return true // 强制在 WebView 内加载
        }


        /**
        在 Android 7.0 以下设备上​​：

        ​​只会触发旧方法​​（带 String url 参数）
        兼容旧版本（API < 24）
         * 跳转拦截处理
         * 打开网页时，不调用系统浏览器进行打开，而是在本WebView中直接显示
         */
        override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
            Log.d(TAG, "shouldOverrideUrlLoading: $url")
            //处理url
            view?.loadUrl(url)
            return true
        }

        /**
         * 设置错误页面
         */
        override fun onReceivedError(webview: WebView?, p1: Int, p2: String?, p3: String?) {
            super.onReceivedError(webview, p1, p2, p3)
        }

        override fun onReceivedSslError(
            webView: WebView?,
            handler: SslErrorHandler?,
            error: SslError?
        ) {
            super.onReceivedSslError(webView, handler, error)
            //忽略ssl错误
            handler?.proceed()
        }
    }

    override fun initObserve() {}


    override fun initRequestData() {}


    override fun onDestroy() {
        animator?.cancel()//动画要记得关掉。profile分析不出来，，，，我滴妈。。。。
        // 解绑所有用例
        cameraProvider.unbindAll()
        super.onDestroy()
    }

    //发现只要一返回就直接关掉了，但如果我想返回上一页呢？就需要如下这样。
    override fun onBackPressed() {
        if (mBinding.webView.canGoBack()) {
            mBinding.webView.goBack() // 返回上一个浏览页
        } else {
            super.onBackPressed()
        }
    }

    private var isMeasuring = false
    private val measurementDuration = 10 // 测量持续时间（秒）

    // 心率计算相关变量
    private val bufferSize = 256
    private val redValues = LinkedList<Double>()
    private var samplingRate = 30.0 // 假设帧率为30fps


    private fun startHeartRateCalculation() {
        lifecycleScope.launch {
            delay(measurementDuration * 1000L)
            isMeasuring = false

            val values = synchronized(redValues) { redValues.toDoubleArray() }

            // 信号处理:拿到信号，转成FFT，找到主屏道率
            val filtered = butterworthBandpassFilter(values)
            val fftResult = performFFT(filtered)
            val heartRate = findDominantFrequency(fftResult)

            runOnUiThread {
                mBinding.test.text = "心率: ${heartRate.roundToInt()} BPM"
            }
        }.start()
    }

    private fun butterworthBandpassFilter(input: DoubleArray): DoubleArray {
        // 简单实现：带通滤波器（0.7Hz ~ 4Hz ≈42-240BPM）
        val filtered = DoubleArray(input.size)
        var prev = input[0]
        var prev2 = input[0]
        for (i in 2 until input.size) {
            filtered[i] = 0.2 * input[i] + 0.6 * prev + 0.2 * prev2
            prev2 = prev
            prev = input[i]
        }
        return filtered
    }

    private fun performFFT(input: DoubleArray): DoubleArray {
        val fft = FastFourierTransformer(DftNormalization.STANDARD)
        //todo 这里会报错，需要进行处理    251 is not a power of 2, consider padding for fix
        val transformed: Array<Complex> = fft.transform(input, TransformType.FORWARD)
        return DoubleArray(transformed.size / 2) {
            transformed[it].abs()
        }
    }

    private fun findDominantFrequency(fftResult: DoubleArray): Double {
        val maxIndex = fftResult.indices.maxByOrNull { fftResult[it] } ?: 0
        return (maxIndex * samplingRate) / fftResult.size * 60
    }

}